/*
 * Copyright (c) 2008 Anshuman Manur <anshuman.manur@gmail.com>,
 * Lavanya Shastri <lavanya.shastri@gmail.com>
 * 
 * This file is part of Andronova.
 * 
 * Andronova is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 * 
 * Andronova is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with Andronova.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * This file may use the functionality provided by the library
 * jid3lib version 0.5.4 (<http://sourceforge.net/projects/javamusictag/>).
 * jid3lib and its uses are covered by GNU Lesser General Public License.
 * 
 */

package com.googlecode.andronova;

import java.io.IOException;

import org.farng.mp3.id3.AbstractID3v2;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;

import com.googlecode.andronova.helper.EndOfPlayListException;
import com.googlecode.andronova.helper.PlayBackOrganiser;
import com.googlecode.andronova.helper.Song;

public class Playback extends Service {
	
	private final MediaPlayer mp = new MediaPlayer();
	
	public static Handler playScreenHandler;
	
	public static PlayBackOrganiser pbOrganiser;
	
	public static final String ACTION = "action";
	
	public static final int ACTION_INIT = 0;
	public static final int ACTION_RESUME = 1;
	public static final int ACTION_PAUSE = 2;
	public static final int ACTION_NEXT = 3;
	public static final int ACTION_PREV = 4;
	public static final int ACTION_STOP = 5;
	
	private String message;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	protected void onCreate() {
		super.onCreate();
		
		mp.setOnCompletionListener(new OnCompletionListener() {
			
			public void onCompletion(MediaPlayer m) {
				next();
				if(playScreenHandler != null)
					playScreenHandler.dispatchMessage(Message.obtain());
			}
			
		});
	}
	
	private String setCurrentSongMessage() {
		Song s = pbOrganiser.getCurrentSong();
		AbstractID3v2 tag = s.getID3v2Tag();
		if(tag == null)
			message = s.getMp3file().getName() + "\nUnknown";
		else {
			String title = tag.getSongTitle();
			String artist = tag.getLeadArtist();
			if(title.equals(""))
				title = s.getMp3file().getName();
			if(artist.equals(""))
				artist = "Unknown";
			message = title + "\n" + artist;
		}
		return message;
	}
	
	private void sendToast() {
		Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
		toast.show();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mp.release();
	}

	@Override
	protected void onStart(int startId, Bundle arguments) {
		super.onStart(startId, arguments);
		
		if(pbOrganiser == null) {
			this.showAlert(PlayScreen.ERROR, android.R.id.icon, "No Song Selected", "OK", false);
			return;
		}
		
		switch(arguments.getInt(ACTION)) {
		case ACTION_INIT:
			try {
				mp.reset();
				Song s = pbOrganiser.getCurrentSong();
				String path = s.getMp3file().getAbsolutePath();
				mp.setDataSource(path);
				mp.prepare();
				mp.start();
				pbOrganiser.setPlaying(true);
				setCurrentSongMessage();
				sendToast();
			}
			catch(IOException e) {
				this.showAlert(PlayScreen.ERROR, android.R.id.icon, "Unable to read file" + "\n" + e.toString(), "OK", false);
				return;
			}
			catch(Exception e) {
				this.showAlert(PlayScreen.ERROR, android.R.id.icon, e.toString(), "OK", false);
				return;
			}
			finally {
				PlayScreen.changed = true;
			}
			break;
				
		case ACTION_RESUME:
			mp.start();
			pbOrganiser.setPlaying(true);
			break;
			
		case ACTION_PAUSE:
			mp.pause();
			pbOrganiser.setPlaying(false);
			break;
			
		case ACTION_NEXT:
			next();
			break;
			
		case ACTION_PREV:
			prev();
			break;
			
		case ACTION_STOP:
			if(pbOrganiser != null)
				pbOrganiser = null;
			stopSelf();
		}
	}
	
	private void next() {
		try {
			mp.stop();
			Song song = pbOrganiser.getNextSong();
			String pathos = song.getMp3file().getAbsolutePath();
			try {
				mp.reset();
				mp.setDataSource(pathos);
				mp.prepare();
				mp.start();
				setCurrentSongMessage();
				sendToast();
			}
			catch(IOException e) {
				this.showAlert(PlayScreen.ERROR, android.R.id.icon, "Unable to read file" + "\n" + e.toString(), "OK", false);
				return;
			}
			catch(Exception e) {
				this.showAlert(PlayScreen.ERROR, android.R.id.icon, e.toString(), "OK", false);
				return;
			}
		}
		catch(EndOfPlayListException eOPE) {
			mp.stop();
			message = "End of Playlist";
			sendToast();
			return;
		}
		catch(IOException e) {
			this.showAlert(PlayScreen.ERROR, android.R.id.icon, "Unable to read file" + "\n" + e.toString(), "OK", false);
			return;
		}
		catch(Exception e) {
			this.showAlert(PlayScreen.ERROR, android.R.id.icon, e.toString(), "OK", false);
			return;
		}
		finally {
			PlayScreen.changed = true;
		}
	}
	
	private void prev() {
		try {
			mp.stop();
			Song song = pbOrganiser.getPrevSong();
			String pathos = song.getMp3file().getAbsolutePath();
			try {
				mp.reset();
				mp.setDataSource(pathos);
				mp.prepare();
				mp.start();
				setCurrentSongMessage();
				sendToast();
			}
			catch(IOException e) {
				this.showAlert(PlayScreen.ERROR, android.R.id.icon, "Unable to read file" + "\n" + e.toString(), "OK", false);
				return;
			}
			catch(Exception e) {
				this.showAlert(PlayScreen.ERROR, android.R.id.icon, e.toString(), "OK", false);
				return;
			}
		}
		catch(EndOfPlayListException eOPE) {
			mp.stop();
			message = "End of Playlist";
			sendToast();
			return;
		}
		catch(IOException e) {
			this.showAlert(PlayScreen.ERROR, android.R.id.icon, "Unable to read file" + "\n" + e.toString(), "OK", false);
			return;
		}
		catch(Exception e) {
			this.showAlert(PlayScreen.ERROR, android.R.id.icon, e.toString(), "OK", false);
			return;
		}
		finally {
			PlayScreen.changed = true;
		}
	}
}
